"use strict";
const mvc = require("cosjs.mvc");
const fields = ['lv', 'sid', 'name', 'icon', 'teachers'];
const equipbag = 30;

/*通用BUFF计算
k:属性ID
v:附加值
t: 0-数值，1百分百
o: 字母O，>=0 加，小于0：减
*/
function sumBuffAttr(attr, buff) {
    if (!buff || typeof buff != 'object') {
        buff = { 'k': arguments[1], 'v': arguments[2] || 0, 't': arguments[3] || 0, 'o': arguments[4] || 1 };
    }
    if (!buff['v']) {
        return true;
    }
    buff["o"] = buff["o"] >= 0 ? 1 : -1;
    let k = buff['k'];
    if (!attr[k]) {
        return mvc.library('debug', 'sumBuffAttr k error', JSON.stringify(buff));
    }
    let t = buff['t'];
    while (t > attr[k].length - 1) {
        attr[k].push(0)
    }
    // if (!(t in attr[k])) {
    //     return true;
    // }
    attr[k][t] += (buff['v'] * buff['o']);
    //
    // if (t > 1) {
    //     console.log(buff['v'] * buff['o'])
    //     attr[k].push(buff['v'] * buff['o']);
    // } else {
    // }

}

/*批量添加BUFF
 ratio : 比例，如果不为0，buff中每一项都会进行 buff['v'] = buff['v'] * ratio 运算
 */
function sumBuffAttrFromArr(attr, buffs, ratio) {
    if (!buffs || !buffs.length) {
        return;
    }
    for (let buff of buffs) {
        let v = ratio ? buff['v'] * ratio : buff['v'];
        sumBuffAttr(attr, buff['k'], v, buff['t'] || 0, buff['o']);
    }
}

//通用计算BUFF属性
exports.buff = function (attr, buff) {
    if (Array.isArray(buff)) {
        return sumBuffAttrFromArr(...arguments);
    } else {
        return sumBuffAttr(...arguments);
    }
}
//玩家战斗属性 uid,corps,pos,keys:额外参数,opts:{"buff","skill","scale"...}
exports.player = async function (uid, corps, equips = [], pos, keys = [], opts = {}, buffs = []) {
    if (!uid) {
        return await Promise.reject("uid empty")
    }
    if (!corps) {
        return await mvc.library("promise/callback", "user_corps_empty", corps)
    }
    let updater = typeof uid === 'object' ? uid : mvc.library('updater', uid, this.sid);
    keys = keys.concat(fields);
    updater.role.key(keys);
    let result = { "heros": {} };
    let corpsTypes = new Map();
    //查询需要用到的ID
    let findItemsSet = new Set(equips);

    for (let k of corps) {
        if (!k) continue
        let ty = updater.item.key(k);
        if (corpsTypes.has(k)) {
            return mvc.library("promise/callback", "user_corps_error", k)
        }
        let hc = mvc.config("hero", ty.id);
        if (!hc) {
            return mvc.library("promise/callback", "config not exist", "hero", ty.id);
        }
        corpsTypes.set(k, ty);

    }

    await updater.data();

    let i = 0
    for (let [k, t] of corpsTypes) {
        let v = updater.item.get(t);
        if (!v) {
            return mvc.library("promise/callback", "hero_not_exist", k)
        }
        v.skill = getFinalSkill(v);
        v.buffs = buffs;
        v.equip = [];
        // v.attach = mvc.library("arrmap/attach","hero",v.attach);
        v.pos = pos[i++];
        // if(v.attach.soldier){
        //     soldier.add(v.attach.soldier);
        // }
        result.heros[k] = v;
    }
    //获取所有用到的装备
    let query = { "$or": [] };
    // let query = {};
    //装备
    // query["$or"].push({"use": {"$in": corps}});
    // query.id = {"$in": Array.from(findItemsSet)}
    query["$or"].push({ "_id": { "$in": Array.from(findItemsSet) } });
    let ret = await updater.item.find(query);

    if (!ret) {
        return;
    }

    for (let i = 0; i < equips.length; i++) {
        let ek = equips[i]
        let hk = corps[Math.floor(i / 4)]
        if (ret[ek]) {
            result["heros"][hk]["equip"].push(ret[ek]);
        }
    }
    // for (let k in ret) {
    //     let d = ret[k];
    //     if (d['bag'] != equipbag || !d['use']) continue;
    //     let hk = d['use'];
    //     result["heros"][hk]["equip"].push(d);
    // }
    result.heros = mvc.library.call(updater, "hero/corps", result["heros"], opts)

    for (let k of keys) {
        result[k] = updater.role.get(k);
    }

    return result

}


//机器人战斗属性
exports.robot = async function (id) {
    let i = arguments[1] || 0;
    let robot = mvc.config("robot", id);

    if (!robot) {
        return await mvc.library("promise/callback", "config_not_exist", ["robot", id]);
    }

    let uid = await mvc.library('guid/uid', this.sid, null, 0);
    let updater = mvc.library('updater', uid, this.sid);

    let result = Object.from(robot, fields);
    result['_id'] = ['z', i, id].join('');

    let robotPos = mvc.config("robotPos", robot['robotPos']);
    if (!robotPos) {
        return mvc.library("promise/callback", "config_not_exist", ["robotPos", robot['robotPos']]);
    }

    let heroes = {};
    let j = 0
    for (let v of robot['monster']) {
        if (!v) continue
        let c = JSON.clone(mvc.config('monster', v))
        if (!c) continue
        let hc = mvc.config('hero', c.heroid)
        let d = {
            '_id': ['z', c['id']].join(''),
            'id': c['heroid'],
            'lv': c.lv,
            'slv': c.star,
            'mid': c.ai,
            'blv': 0,
            // "talent": [],
            "skill": [hc.skill[0], ...c.extra],
            "buffs": arguments[3] || [],
            "equip": [],
            "pos": robotPos.pos[j++],
        };

        d.buffs = d.buffs.concat(c.buff)

        d.scale = c['attrScale']

        if (d.skill.length === 1) {
            d.skill.push(0)
            d.skill.push(0)
        }
        if (d.skill.length === 1) {
            d.skill.push(0)
        }

        if (arguments[2] && Array.isArray(arguments[2])) {
            for (let i of arguments[2]) {
                if (i) d.skill.push(Number(i))
            }
        }

        heroes[d._id] = d;
    }

    result['heros'] = mvc.library.call(updater, "hero/corps", heroes);

    return result;

}


//hero为卡牌
function getFinalSkill(hero) {
    let finalSkill = JSON.clone(hero.skills)
    let hc = mvc.config('hero', hero.id)
    if (!hero.slv || !hc) {
        return finalSkill
    }
    let sid = hc.star_group * 1000 + hero.slv;
    let sConfig = mvc.config('heroStar', sid);
    for (let i = 0; i < 2; i++) {
        if (sConfig.skill[i] && finalSkill[i]) {
            //改变技能
            //觉醒的技能ID固定+50
            finalSkill[i] += 50;
        }
    }

    return finalSkill;
}